home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 22 / AACD 22.iso / AACD / Sound / Subspace68k / src / Subspace68k.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-05-04  |  32.6 KB  |  1,276 lines

  1. #define P96 //SuRgEoN :for compatibility - still through cgfx
  2.  
  3. #define MAXWIDTH  640
  4. #define MAXHEIGHT 480
  5.  
  6. #define NUMFIELDS 19
  7. #define NUMWAVES 12
  8.  
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <time.h>
  13. #include <math.h>
  14.  
  15. #include <exec/types.h>
  16. #include <exec/memory.h>
  17. #include <proto/exec.h>
  18. #include <proto/dos.h>
  19. #include <proto/intuition.h>
  20. #include <proto/graphics.h>
  21. #include <proto/cybergraphics.h>
  22. #include <proto/icon.h>
  23. #include <proto/keymap.h>
  24. #include <devices/timer.h>
  25. #include <proto/timer.h>
  26. #include <exec/devices.h>
  27.  
  28. #include <workbench/startup.h>
  29. #include <dos/dostags.h>
  30. #include <graphics/gfxbase.h>
  31. #include <cybergraphx/cybergraphics.h>
  32.  
  33. #ifdef __SASC
  34. struct Library *PPCLibBase;
  35. #include <PowerUP/PPCLib/tasks.h>
  36. ULONG    PPCCallOS(struct Caos*);
  37. ULONG    PPCSetTaskAttrs(void*, struct TagItem*);
  38.  
  39. #define    PPCSetTaskAttrs(TaskObject, Tags)    _PPCSetTaskAttrs(PPC_BASE_NAME, TaskObject, Tags)
  40. static __inline ULONG _PPCSetTaskAttrs(void *PPCLibBase, void*TaskObject, struct TagItem*Tags) {
  41.     struct Caos    MyCaos;
  42.     MyCaos.M68kCacheMode    =    IF_CACHEFLUSHALL;
  43.     MyCaos.PPCCacheMode    =    IF_CACHEFLUSHALL;
  44.     MyCaos.a0        =(ULONG) TaskObject;
  45.     MyCaos.a1        =(ULONG) Tags;
  46.     MyCaos.caos_Un.Offset    =    (-192);
  47.     MyCaos.a6        =(ULONG) PPCLibBase;    
  48.     return((ULONG)PPCCallOS(&MyCaos));
  49. }
  50. #endif
  51.  
  52.  
  53. #include "TrackInfo.h"
  54.  
  55. BOOL PluginInit(int argc, char **argv);
  56. void PluginExit(void);
  57. void PluginLoop(void); //mainloop for viasualization effects
  58. void ShowRequester(char *Text, char *Button);
  59. struct MsgPort *MyCreatePort(UBYTE *name, LONG pri);
  60. void MyDeletePort(struct MsgPort *mp);
  61.  
  62. /***************************************************************************/
  63. /* This is the global variables section. Don't change anything here unless */
  64. /* you know what you're doing!                                             */
  65. /***************************************************************************/
  66.  
  67. BYTE             PluginSignal, InfoSignal, ConfigSignal;
  68. ULONG            PluginMask,   InfoMask,   ConfigMask;
  69. BOOL             Accepted;
  70. struct Process   *PluginTask;
  71. struct MsgPort   *PluginMP;
  72. struct MsgPort   *PluginRP;
  73. struct TrackInfo *tinfo;
  74.  
  75. #ifdef __SASC
  76. struct Library     *TimerBase;
  77. #else
  78.  #ifdef __VBCC__ //SuRgEoN
  79. struct Library      *TimerBase = NULL;
  80.  #else
  81. struct Device      *TimerBase;
  82.  #endif
  83. #endif
  84. struct MsgPort     *TimerMP;
  85. struct timerequest *TimerIO = NULL;
  86. struct EClockVal   ev1;
  87. struct EClockVal   ev2;
  88. BYTE               TimerError = -1;
  89. ULONG              EFreq=0;
  90. ULONG              TimerMask;
  91.  
  92. UWORD    TrackInfoPos = 1;
  93.  
  94. UWORD    *PluginRawL;
  95. UWORD    *PluginRawR;
  96. WORD    *PluginSamples;
  97. UWORD    *SpecRawL;
  98. UWORD    *SpecRawR;
  99. WORD *SampleRaw;
  100.  
  101. struct PluginMessage {
  102.     struct Message   msg;
  103.     ULONG            PluginMask;
  104.     struct Process   *PluginTask;
  105.     UWORD            **SpecRawL;
  106.     UWORD            **SpecRawR;
  107.     UWORD            Accepted;
  108.     UWORD            reserved0;
  109.     ULONG            InfoMask;
  110.     struct TrackInfo **tinfo;
  111.     ULONG            ConfigMask;
  112.     WORD             **SampleRaw;
  113. };
  114.  
  115. BOOL OpenTimer(void);
  116. void CloseTimer(void);
  117. void StartTimer(void);
  118.  
  119. /***************************************************************************/
  120. /* This is the main part. Again, don't change anything here if you haven't */
  121. /* got a very good reason to do so!                                        */
  122. /***************************************************************************/
  123.  
  124. int main(int argc, char **argv) {
  125.     struct PluginMessage *PluginMsg;
  126.     struct PluginMessage *ReplyMsg;
  127.  
  128.  
  129.     /* Allocate all user resources */
  130.     if(PluginInit(argc, argv)) {
  131.         /* Check if a plugin capable instance of AmigaAMP is running */
  132.         if(PluginMP=FindPort("AmigaAMP plugin port"))    {
  133.             /* Allocate some sigbits for receiving signals FROM AmigaAMP */
  134.             PluginSignal = AllocSignal(-1);
  135.             ConfigSignal = AllocSignal(-1);
  136.             InfoSignal   = AllocSignal(-1);
  137.             PluginTask   = (struct Process *)FindTask(NULL);
  138.  
  139.             if(PluginSignal != -1 && InfoSignal != -1 && PluginSignal != -1) {
  140.                 PluginMask = 1L << PluginSignal;
  141.                 ConfigMask = 1L << ConfigSignal;
  142.                 InfoMask   = 1L << InfoSignal;
  143.  
  144.                 /* Allocate a message and reply port for sending messages TO AmigaAMP */
  145.                 #if defined (__SASC) || defined (__VBCC__) //SuRgEoN
  146. #ifdef __PPC__
  147.                 PluginMsg=PPCAllocVec(sizeof(struct PluginMessage), MEMF_PUBLIC|MEMF_CLEAR);
  148. #else
  149.                 PluginMsg=AllocVec(sizeof(struct PluginMessage), MEMF_PUBLIC|MEMF_CLEAR);
  150. #endif
  151.                 PluginRP=(struct MsgPort*)MyCreatePort(0,0);
  152.                 #else
  153.                 PluginMsg=AllocVecPPC(sizeof(struct PluginMessage), MEMF_PUBLIC|MEMF_CLEAR, 0);
  154.  
  155.                 PluginRP=(struct MsgPort*)CreatePort(0,0);
  156.                 #endif
  157.  
  158.                 /* Tell AmigaAMP all the details it needs to know */
  159.                 PluginMsg->msg.mn_Node.ln_Type = NT_MESSAGE;
  160.                 PluginMsg->msg.mn_Length       = sizeof(struct PluginMessage);
  161.                 PluginMsg->msg.mn_ReplyPort    = PluginRP;
  162.                 PluginMsg->PluginMask          = PluginMask;
  163.                 PluginMsg->PluginTask          = PluginTask;
  164.                 PluginMsg->SpecRawL            = &SpecRawL;
  165.                 PluginMsg->SpecRawR            = &SpecRawR;
  166.                 PluginMsg->InfoMask            = InfoMask;
  167.                 PluginMsg->tinfo               = &tinfo;
  168.                 PluginMsg->ConfigMask          = ConfigMask;
  169.                 PluginMsg->SampleRaw           = &SampleRaw;
  170.                 PutMsg(PluginMP, (struct Message *)PluginMsg);
  171.                 /* Wait for a reply */
  172.                 WaitPort(PluginRP);
  173.                 /* Let's see if AmigaAMP accepted our registration attempt */
  174.                 if(ReplyMsg = (struct PluginMessage *)GetMsg(PluginRP)) Accepted=ReplyMsg->Accepted;
  175.                 else Accepted=FALSE;
  176.  
  177.                 if(Accepted) {
  178.                     /* If it did, start the plugin loop */
  179.                     printf("Init ok! - entering plugin loop\n");
  180.                     PluginLoop();
  181.  
  182.                     /* Tell AmigaAMP that this plugin is going down */
  183.                     PluginMsg->PluginMask          = 0;
  184.                     PluginMsg->PluginTask          = NULL;
  185.                     PluginMsg->SpecRawL            = NULL;
  186.                     PluginMsg->SpecRawR            = NULL;
  187.                     PluginMsg->ConfigMask          = 0;
  188.                     PluginMsg->InfoMask            = 0;
  189.                     PluginMsg->tinfo               = NULL;
  190.                     PluginMsg->SampleRaw           = NULL;
  191.                     PutMsg(PluginMP, (struct Message *)PluginMsg);
  192.                     /* Wait for confirmation before going on! */
  193.                     WaitPort(PluginRP);
  194.                     GetMsg(PluginRP);
  195.                     /* Now that AmigaAMP knows that we're gone, we can quit */
  196.                 }
  197.                 else {
  198.                     /* If AmigaAMP didn't accept us, tell the user about it */
  199.                     ShowRequester("Plugin rejected by AmigaAMP!\nPerhaps there's another one running.", "Abort");
  200.                 }
  201.  
  202.                 /* Free all resources */
  203.                 #ifdef __SASC
  204.  
  205.                     PPCFreeVec(PluginMsg);
  206.                     MyDeletePort(PluginRP);
  207.                 #else
  208.                     #ifndef PPC__ //SuRgEoN
  209.                     FreeVec(PluginMsg);
  210.                     DeletePort(PluginRP);
  211.                     #else
  212.                     FreeVecPPC(PluginMsg);
  213.                     DeletePort(PluginRP);
  214.                     #endif
  215.                 #endif
  216.             }
  217.             else {
  218.                 ShowRequester("Signal allocation failure!", "Abort");
  219.             }
  220.             if(PluginSignal != -1) FreeSignal(PluginSignal);
  221.             if(ConfigSignal != -1) FreeSignal(ConfigSignal);
  222.             if(InfoSignal   != -1) FreeSignal(InfoSignal);
  223.         }
  224.         else {
  225.             ShowRequester("Could not find message port!\nAmigaAMP probably not running.", "Abort");
  226.         }
  227.     }
  228.     else {
  229.         ShowRequester("Plugin initialisation failed!", "Ok");
  230.     }
  231.     /* Free all user resources */
  232.     PluginExit();
  233. }
  234.  
  235. /*****************************************************************************/
  236. /* Ok, now for the individual plugin sourcecode. Everything below should be  */
  237. /* changed to your needs.                                                    */
  238. /* Just like before, we start with the global variables section              */
  239. /*****************************************************************************/
  240.  
  241. void InitWave(UBYTE WaveNum, ULONG BufNum);
  242. void CalcWave(UBYTE WaveNum, ULONG BufNum);
  243. void DrawWave(LONG *WaveX, LONG *WaveY, ULONG Width, ULONG Height, UBYTE WaveNum, ULONG BufNum);
  244.  
  245. void InitField(LONG *Zoom, ULONG Width, ULONG Height);
  246. void PrepareConstants(UBYTE FieldNum);
  247. void CalcLine(LONG *Zoom, ULONG Width, ULONG Height, UBYTE FieldNum);
  248. void MakeCMap(void);
  249. void Blur(UBYTE *PixelC, UBYTE *PixelD);
  250. void ReColor(void);
  251. void MakeTitle(void);
  252. float rnd(float max);
  253. float sgn(float val);
  254.  
  255. const char VersionString[]="\0$VER: Subspace 1.1 (10.11.00)";
  256. const char Line1[]="Subspace";
  257. const char Line2[]="by Thomas Wenzel";
  258.  
  259. #define PRECISION PRECISION_EXACT
  260.  
  261. struct IntuitionBase *IntuitionBase = NULL;
  262. struct GfxBase *GfxBase      = NULL;
  263. struct Library *IconBase     = NULL;
  264. struct Library *KeymapBase   = NULL;
  265. struct Library *AslBase      = NULL;
  266. struct Library *GadToolsBase = NULL;
  267. struct Library *CyberGfxBase = NULL;
  268. struct Screen  *PluginScreen = NULL;
  269. struct Window  *PluginWin    = NULL;
  270. struct RastPort *rp;
  271. struct ViewPort *vp;
  272.  
  273.  
  274. struct EClockVal ev1;
  275. struct EClockVal ev2;
  276.  
  277.  
  278. ULONG ModeID;
  279. ULONG WinMask;
  280.  
  281. UBYTE *PixelD;
  282. UBYTE *PixelC;
  283. ULONG *Colour;
  284.  
  285. UWORD *EmptyPointer;
  286.  
  287. char InfoLine[256];
  288.  
  289. LONG Zoom[MAXWIDTH*MAXHEIGHT];
  290. LONG Zoom2[MAXWIDTH*MAXHEIGHT];
  291. LONG WaveX[MAXWIDTH*2];
  292. LONG WaveY[MAXWIDTH*2];
  293. LONG WaveX2[MAXWIDTH*2];
  294. LONG WaveY2[MAXWIDTH*2];
  295.  
  296. ULONG MidR[4], MidG[4], MidB[4];
  297. ULONG DisplayFPS;
  298. ULONG ShowWave;
  299. ULONG LimitFPS;
  300. #ifdef __PPC__
  301. ULONG ScreenSize = 100;
  302. #else
  303. ULONG ScreenSize = 66;
  304. #endif
  305. #ifdef PPC
  306. ULONG Width      = 320;
  307. ULONG Height     = 240;
  308. ULONG HalfHeight = 120;
  309. #else
  310. ULONG Width      = 240;
  311. ULONG Height     = 180;
  312. ULONG HalfHeight = 90;
  313. #endif
  314.  
  315. ULONG Cutoff     = 1;
  316. ULONG InfoCount;
  317. ULONG FrameCountLow;
  318. ULONG FrameCountHigh;
  319. ULONG FrameCountWave;
  320. ULONG FrameCountField;
  321. ULONG TimeWave;
  322. ULONG DestWaveNum;
  323. ULONG DestWaveBuffer;
  324. float WaveMorph;
  325. ULONG MidRdst[3], MidGdst[3], MidBdst[3];
  326. ULONG LineToCalc;
  327. UBYTE FieldToCalc;
  328. UBYTE WaveToCalc, WaveToCalc0, WaveToCalc1;
  329. UBYTE PrevField;
  330.  
  331. /****************************************************************************/
  332. /* This function will be called once when the plugin is started. You should */
  333. /* allocate all needed resources here. Return TRUE if all went well.        */
  334. /****************************************************************************/
  335.  
  336. BOOL PluginInit(int argc, char **argv) {
  337.     long i,xs,ys,xd,yd,ysp,ydp;
  338.     float xf,yf;
  339.     UBYTE **ttypes = 0; //VBCC
  340.     char *str;
  341.     struct DiskObject *IconObj = NULL; //VBCC
  342.     struct WBStartup  *WBStart = NULL; //VBCC
  343.     #ifdef __SASC
  344.     void *ThisTask;
  345.     #else
  346.     struct TaskPPC *ThisTask;
  347.     #endif
  348.     WORD Length;
  349.  
  350. #ifdef __PPC__
  351.     struct TagItem ModeIDtags[] = {
  352.         CYBRBIDTG_Depth, 8, CYBRBIDTG_NominalWidth, 320, CYBRBIDTG_NominalHeight, 240, TAG_DONE
  353.     };
  354. #else
  355.     struct TagItem ModeIDtags[] = {
  356.         CYBRBIDTG_Depth, 8, CYBRBIDTG_NominalWidth, 320, CYBRBIDTG_NominalHeight, 200, TAG_DONE
  357.     };
  358. #endif
  359.     AslBase=OpenLibrary("asl.library", 0);
  360.     if(!AslBase) {
  361.         ShowRequester("Can't open asl.library!", "Abort");
  362.         return(FALSE);
  363.     }
  364.  
  365.     IconBase=OpenLibrary("icon.library", 0);
  366.     if(!IconBase) {
  367.         ShowRequester("Can't open icon.library!", "Abort");
  368.         return(FALSE);
  369.     }
  370.  
  371.     KeymapBase=OpenLibrary("keymap.library", 0);
  372.     if(!KeymapBase) {
  373.         ShowRequester("Can't open keymap.library!", "Abort");
  374.         return(FALSE);
  375.     }
  376.  
  377.     IntuitionBase=(struct IntuitionBase*)OpenLibrary("intuition.library", 0);
  378.     if(!IntuitionBase) {
  379.         ShowRequester("Can't open intuition.library!", "Abort");
  380.         return(FALSE);
  381.     }
  382.  
  383.     GadToolsBase=OpenLibrary("gadtools.library", 0);
  384.     if(!GadToolsBase) {
  385.         ShowRequester("Can't open gadtools.library!", "Abort");
  386.         return(FALSE);
  387.     }
  388.  
  389.     GfxBase=(struct GfxBase*)OpenLibrary("graphics.library", 0);
  390.     if(!GfxBase) {
  391.         ShowRequester("Can't open graphics.library!", "Abort");
  392.         return(FALSE);
  393.     }
  394.  
  395.     if(GfxBase->LibNode.lib_Version < 39) {
  396.         ShowRequester("This plugin requires AmigaOS 3.0 or greater!", "Abort");
  397.         return(FALSE);
  398.     }
  399.  
  400.     CyberGfxBase=OpenLibrary("cybergraphics.library", 40);
  401.     if(!CyberGfxBase) {
  402.         ShowRequester("This plugin requires CyberGraphX v3 or higher!", "Abort");
  403.         return(FALSE);
  404.     }
  405.  
  406.     #ifdef __SASC
  407.         /* Increase the priority of the 68k mirror task */
  408.         SetTaskPri(FindTask(NULL), 15);
  409.         /* Increase our own priority (if it only would work...) */
  410.         PPCSetTaskAttr(PPCTASKTAG_PRIORITY, 15);
  411.     #else
  412.         #ifdef __VBCC__
  413.     //        SetTaskPri(FindTask(NULL), 15);
  414.         #else
  415.         /* Increase our own priority */
  416.         ThisTask = FindTaskPPC(NULL);
  417.         SetNiceValue(ThisTask, -15);
  418.         #endif
  419.     #endif
  420.  
  421.     WBStart=(struct WBStartup *)argv;
  422.  
  423. // if(argc==0) printf("IconName: %s\n", WBStart->sm_ArgList[0].wa_Name);
  424.  
  425.     if(argc==0) IconObj=GetDiskObject(WBStart->sm_ArgList[0].wa_Name);
  426.     else        IconObj=GetDiskObject(argv[0]);
  427.  
  428.     LimitFPS = 999;
  429.  
  430.     if(IconObj) {
  431.         if(str=FindToolType(IconObj->do_ToolTypes,"MAXFPS"))
  432.         {
  433.             LimitFPS = atol(str);
  434.         }
  435.  
  436.         if(str=FindToolType(IconObj->do_ToolTypes,"RESOLUTION"))
  437.         {
  438.             if(stricmp(str,"high") == 0) {
  439.                 Width      = 640;
  440.                 Height     = 480;
  441.                 ScreenSize = 66;
  442.             }
  443.             else {
  444. #ifdef __PPC__
  445.                 Width      = 320;
  446.                 Height     = 240;
  447.                 ScreenSize = 100;
  448. #else
  449.                 Width      = 240;
  450.                 Height       = 180;
  451.                 ScreenSize = 66;
  452. #endif
  453.  
  454.             }
  455.         }
  456.  
  457.         if(str=FindToolType(IconObj->do_ToolTypes,"SCREENSIZE"))
  458.         {
  459.             ScreenSize = atol(str);
  460.         }
  461.     FreeDiskObject(IconObj);
  462.     }
  463.  
  464.     if(ttypes=(UBYTE**)ArgArrayInit(argc, argv)) {
  465.         str=(char*)ArgString(ttypes, "MAXFPS", "0");
  466.         LimitFPS = atol(str);
  467.  
  468.         str=(char*)ArgString(ttypes, "RESOLUTION", "low");
  469.         if(stricmp(str,"high") == 0) {
  470.             Width      = 640;
  471.             Height     = 480;
  472.             ScreenSize = 66;
  473.             ShowWave   = 1;
  474.         }
  475.         else {
  476. #ifdef __PPC__
  477.             Width      = 320;
  478.             Height     = 240;
  479.             ScreenSize = 100;
  480. #else
  481.             Width      = 240;
  482.             Height       = 180;
  483.             ScreenSize = 66;
  484. #endif
  485.             ShowWave   = 0;
  486.         }
  487.  
  488.         if(str=(char*)ArgString(ttypes, "SCREENSIZE", NULL)) {
  489.             ScreenSize = atol(str);
  490.         }
  491.  
  492.         ArgArrayDone();
  493.     }
  494.  
  495.     if(LimitFPS == 0)  LimitFPS = 999;
  496.     if(LimitFPS > 999) LimitFPS = 999;
  497.  
  498.     if(ScreenSize <  25) ScreenSize =  25;
  499.     if(ScreenSize > 100) ScreenSize = 100;
  500.  
  501.     Cutoff = Height * (100-ScreenSize) / 200;
  502.     if(Cutoff <   1) Cutoff =   1;
  503.     if(Cutoff > 200) Cutoff = 200;
  504.  
  505.     ModeIDtags[1].ti_Data = Width;
  506.     ModeIDtags[2].ti_Data = Height;
  507.  
  508.     HalfHeight = Height/2;
  509.  
  510.     #if defined (__SASC) || defined (__VBCC__)
  511.         #ifdef __PPC__
  512.         PixelD       = PPCAllocVec(Width*Height, MEMF_PUBLIC|MEMF_CLEAR);
  513.         PixelC       = PPCAllocVec(Width*Height, MEMF_PUBLIC|MEMF_CLEAR);
  514.         Colour       = PPCAllocVec(770*4,        MEMF_PUBLIC|MEMF_CLEAR);
  515.         EmptyPointer = PPCAllocVec(512,          MEMF_CHIP|MEMF_CLEAR);
  516.         #else //68k
  517.         PixelD       = AllocVec(Width*Height, MEMF_PUBLIC|MEMF_CLEAR);
  518.         PixelC       = AllocVec(Width*Height, MEMF_PUBLIC|MEMF_CLEAR);
  519.         Colour       = AllocVec(770*4,        MEMF_PUBLIC|MEMF_CLEAR);
  520.         EmptyPointer = AllocVec(512,          MEMF_CHIP|MEMF_CLEAR);
  521.         #endif
  522.     #else
  523.         PixelD       = AllocVecPPC(Width*Height, MEMF_PUBLIC|MEMF_CLEAR, 0);
  524.         PixelC       = AllocVecPPC(Width*Height, MEMF_PUBLIC|MEMF_CLEAR, 0);
  525.         Colour       = AllocVecPPC(770*4,        MEMF_PUBLIC|MEMF_CLEAR, 0);
  526.         EmptyPointer = AllocVecPPC(512,          MEMF_CHIP|MEMF_CLEAR,   0);
  527.     #endif
  528.  
  529.     OpenTimer();
  530.  
  531.     if(PixelD==NULL || PixelC==NULL) {
  532.         ShowRequester("Out of memory for graphics buffers!", "Abort");
  533.         return(FALSE);
  534.     }
  535.  
  536.     srand(time(NULL));
  537.  
  538.     MidR[0] = 255;
  539.     MidG[0] = 255;
  540.     MidB[0] = 127;
  541.  
  542.     MidR[1] = 170;
  543.     MidG[1] = 170;
  544.     MidB[1] = 64;
  545.  
  546.     MidR[2] = 85;
  547.     MidG[2] = 85;
  548.     MidB[2] = 32;
  549.  
  550.     MidR[3] = 0;
  551.     MidG[3] = 0;
  552.     MidB[3] = 0;
  553.  
  554.     MidRdst[0] = (UBYTE)(rand()%25) + 127;
  555.     MidGdst[0] = (UBYTE)(rand()%25) + 127;
  556.     MidBdst[0] = (UBYTE)(rand()%25) + 127;
  557.  
  558.     MidRdst[1] = (UBYTE)(rand()%25) + 96;
  559.     MidGdst[1] = (UBYTE)(rand()%25) + 96;
  560.     MidBdst[1] = (UBYTE)(rand()%25) + 96;
  561.  
  562.     MidRdst[2] = (UBYTE)(rand()%25) + 64;
  563.     MidGdst[2] = (UBYTE)(rand()%25) + 64;
  564.     MidBdst[2] = (UBYTE)(rand()%25) + 64;
  565.  
  566.     DisplayFPS      = 0;
  567.     InfoCount       = 0;
  568.     FrameCountLow   = 0;
  569.     FrameCountHigh  = 0;
  570.     FrameCountWave  = 0;
  571.     FrameCountField = 0;
  572.     TimeWave        = 0;
  573.     DestWaveNum     = 1;
  574.     DestWaveBuffer  = 1;
  575.     WaveMorph       = 0.0;
  576.     LineToCalc      = 0;
  577.     WaveToCalc      = 0;
  578.     WaveToCalc0     = 0;
  579.  
  580.     FieldToCalc     = (UBYTE)rand() % NUMFIELDS;
  581.     WaveToCalc1     = (UBYTE)rand() % NUMWAVES;
  582.     FieldToCalc   = NUMFIELDS-1;
  583.     WaveToCalc1   = NUMWAVES-1;
  584.  
  585.  
  586.     PrepareConstants(FieldToCalc);
  587.  
  588.     MakeCMap();
  589. #ifdef P96
  590.     ModeID=CModeRequestTagList(NULL, ModeIDtags);
  591. #else
  592.     ModeID=BestCModeIDTagList(ModeIDtags);
  593. #endif
  594.     if(ModeID == INVALID_ID) {
  595.         ShowRequester("Could not find suitable screen mode!", "Abort");
  596.         return(FALSE);
  597.   if (ModeID==-1)
  598.         return(FALSE);
  599.     }
  600.  
  601.     PluginScreen=OpenScreenTags(NULL, SA_DisplayID, ModeID, SA_Depth, 8, SA_Width, Width, SA_Height, Height, SA_SharePens, TRUE, SA_ShowTitle, FALSE, SA_Quiet, TRUE, TAG_DONE);
  602.     if(PluginScreen == NULL) {
  603.         ShowRequester("Could not open screen!", "Abort");
  604.         return(FALSE);
  605.     }
  606.     rp = &PluginScreen->RastPort;
  607.     vp = &PluginScreen->ViewPort;
  608.  
  609.     LoadRGB32(vp, Colour);
  610.  
  611.     PluginWin=OpenWindowTags(NULL, WA_CustomScreen, (ULONG)PluginScreen,
  612.                                    WA_Left,         0,
  613.                                    WA_Top,          0,
  614.                                    WA_Width,        Width,
  615.                                    WA_Height,       Height,
  616.                                    WA_SizeGadget,   FALSE,
  617.                                    WA_DragBar,      FALSE,
  618.                                    WA_DepthGadget,  FALSE,
  619.                                    WA_CloseGadget,  FALSE,
  620.                                    WA_Backdrop,     TRUE,
  621.                                    WA_Borderless,   TRUE,
  622.                                    WA_Activate,     TRUE,
  623.                                    WA_AutoAdjust,   TRUE,  // Just to be sure :-)
  624.                                    WA_IDCMP,        IDCMP_RAWKEY | IDCMP_ACTIVEWINDOW | IDCMP_INACTIVEWINDOW,
  625.                                    TAG_DONE);
  626.     if(PluginWin == NULL) {
  627.         ShowRequester("Could not open window!", "Abort");
  628.         return(FALSE);
  629.     }
  630.  
  631.     SetPointer(PluginWin, EmptyPointer, 1, 1, 0, 0);
  632.     SetAPen(rp, 1);
  633.     RectFill(rp, 0, 0, (Width-1), (Height-1));
  634.     SetAPen(rp, 255);
  635.  
  636.     WinMask = 1L << PluginWin->UserPort->mp_SigBit;
  637.  
  638.     InitField(Zoom, Width, Height);
  639.     MakeTitle();
  640.  
  641.     return(TRUE);
  642. }
  643.  
  644. /******************************************************************************/
  645. /* This function will be called when the plugin is shut down. You should free */
  646. /* all previously allocated resources here.                                   */
  647. /******************************************************************************/
  648.  
  649. void PluginExit(void) {
  650.     long i;
  651.  
  652.     if(PluginWin)    CloseWindow(PluginWin);
  653.     if(PluginScreen) CloseScreen(PluginScreen);
  654.     #ifdef __SASC
  655.         if(PixelD)       PPCFreeVec(PixelD);
  656.         if(PixelC)       PPCFreeVec(PixelC);
  657.         if(Colour)       PPCFreeVec(Colour);
  658.         if(EmptyPointer) PPCFreeVec(EmptyPointer);
  659.     #else
  660.      #ifdef __PPC__    
  661.         if(PixelD)       FreeVecPPC(PixelD);
  662.         if(PixelC)       FreeVecPPC(PixelC);
  663.         if(Colour)       FreeVecPPC(Colour);
  664.         if(EmptyPointer) FreeVecPPC(EmptyPointer);
  665.      #else
  666.         if(PixelD)       FreeVec(PixelD);
  667.         if(PixelC)       FreeVec(PixelC);
  668.         if(Colour)       FreeVec(Colour);
  669.         if(EmptyPointer) FreeVec(EmptyPointer);
  670.      #endif
  671.     #endif
  672.  
  673.     CloseTimer();
  674.  
  675.     if(CyberGfxBase)  CloseLibrary(CyberGfxBase);
  676. //    if(GfxBase)       CloseLibrary(GfxBase);
  677.     if(AslBase)       CloseLibrary(AslBase);
  678.     if(IconBase)      CloseLibrary(IconBase);
  679.     if(KeymapBase)    CloseLibrary(KeymapBase);
  680.     if(GadToolsBase)  CloseLibrary(GadToolsBase);
  681. //    if(IntuitionBase) CloseLibrary(IntuitionBase);
  682. }
  683.  
  684. /*******************************************************************************/
  685. /* This is the main Plugin Loop. It will receive a signal matching PluginMask  */
  686. /* each time new spectral data is ready. The data is stored in two arrays,     */
  687. /* UWORD Spec[512] in structures DataL and DataR. The scale is logarithmic,    */
  688. /* 0 means below -96dB, 65535 means 0dB.                                       */
  689. /* No matter how long it takes until your plugin actually processes the data,  */
  690. /* the memory referenced by the array pointers always remains valid!           */
  691. /*                                                                             */
  692. /* Your plugin loop MUST quit when it receives SIGBREAKF_CTRL_C. If you've     */
  693. /* opened a window you should react to the close gadget as well. For full      */
  694. /* screen plugins I strongly recommend checking the ESC key.                   */
  695. /*******************************************************************************/
  696.  
  697. void PluginLoop(void) {
  698.     struct TextExtent te;
  699.     ULONG *PixelL = 0;
  700.     UBYTE *ActPixel;
  701.     ULONG Signals = 0;
  702.     LONG i,j,k;
  703.     LONG l,r;
  704.     LONG x,y;
  705.     UBYTE v;
  706.     UWORD w;
  707.     UBYTE ColorMode;
  708.  
  709.     ULONG    hi,lo,itime,eclock;
  710.     char FPStext[64];
  711.  
  712.     UBYTE Vanilla;
  713.     struct InputEvent ie;
  714.     WORD    RawLen;
  715.     printf("entering main loop\n");
  716.     Wait(SIGBREAKF_CTRL_C | PluginMask);
  717.  
  718.     /* Make a backup of the data pointers */
  719.     PluginRawL    = SpecRawL;
  720.     PluginRawR    = SpecRawR;
  721.     PluginSamples = SampleRaw;
  722.  
  723.     WritePixelArray(PixelC, 0, 0, Width, rp, 0, 0, Width, Height, RECTFMT_LUT8);
  724.     Delay(100);
  725.  
  726.     StartTimer();
  727.  
  728.     InitWave(WaveToCalc0, 0);
  729.     InitWave(WaveToCalc1, 1);
  730.  
  731.     for(;;) {
  732.         /* Wait until there's something to do */
  733.  
  734.         Signals=Wait(SIGBREAKF_CTRL_C | PluginMask | ConfigMask | InfoMask | WinMask | TimerMask);
  735.         if(Signals & TimerMask) {
  736.             WaitIO((struct IORequest *) TimerIO);
  737.         }
  738.  
  739.         /* Break received -> quit at once! */
  740.         if(Signals & SIGBREAKF_CTRL_C) break;
  741.  
  742.         /* Window close gadget hit -> quit as well! */
  743.         if(Signals & WinMask) {
  744.             struct IntuiMessage *imsg;
  745.             BOOL done=0;
  746.  
  747.             while(imsg=(struct IntuiMessage *)GetMsg(PluginWin->UserPort)) {
  748.                 if(imsg->Class == IDCMP_RAWKEY) {
  749.                     ie.ie_Class        = IECLASS_RAWKEY;
  750.                     ie.ie_SubClass     = 0;
  751.                     ie.ie_Code         = imsg->Code;
  752.                     ie.ie_Qualifier    = 0;
  753.                     ie.ie_EventAddress = imsg->IAddress;
  754.                     RawLen = MapRawKey(&ie, &Vanilla, 1, 0);
  755.  
  756.                     switch(imsg->Code) {
  757.                         case 0x45: done=1; break;
  758.                     }
  759.  
  760.                     if(RawLen==1) {
  761.                         switch(Vanilla) {
  762.                             case 'f': DisplayFPS = 1-DisplayFPS; break;
  763.                             case 'w': ShowWave   = 1-ShowWave;   break;
  764.                             case 'i': InfoCount  = 0;            break;
  765. //                        case '+': Cutoff--;                  break;
  766. //                        case '-': Cutoff++;                  break;
  767.                         }
  768.                         if(Cutoff < 1) Cutoff =   1;
  769.                         if(Cutoff > HalfHeight-10) Cutoff = HalfHeight-10;
  770.                         for(i=0; i<Width*Cutoff; i++) {
  771.                             PixelC[i]=PixelD[i]=0;
  772.                         }
  773.                         for(i=Width*(Height-Cutoff); i<Width*Height; i++) {
  774.                             PixelC[i]=PixelD[i]=0;
  775.                         }
  776.                     }
  777.                 }
  778.                 ReplyMsg(imsg);
  779.             }
  780.             if(done) break;
  781.         }
  782.  
  783.         if(Signals & TimerMask) {
  784.             StartTimer();
  785. //printf("timer started\n");
  786.       Blur(PixelC, PixelD);
  787.  
  788.             FrameCountLow++;
  789.             if(FrameCountLow > 4) {
  790.                 FrameCountLow = 0;
  791.                 eclock=ReadEClock(&ev2);
  792.                 hi = ev2.ev_hi - ev1.ev_hi;
  793.                 lo = ev2.ev_lo - ev1.ev_lo;
  794.                 itime = hi*eclock+lo;
  795.  
  796.                 if(itime==0) itime=1;
  797.  
  798.                 ev1.ev_hi = ev2.ev_hi;
  799.                 ev1.ev_lo = ev2.ev_lo;
  800.                 ReColor();
  801.             }
  802.  
  803.             FrameCountHigh++;
  804.         if(FrameCountHigh > 600) {
  805.                 FrameCountHigh = 0;
  806.  
  807.                 ColorMode = (UBYTE)rand()% 10;
  808.  
  809.             printf("ColorMode: %d\n", ColorMode);
  810.                 switch(ColorMode) {
  811.                     case 0:
  812.                     case 1:
  813.                         MidRdst[0] = (UBYTE)(rand()%25) + 127;
  814.                         MidGdst[0] = (UBYTE)(rand()%25) + 127;
  815.                         MidBdst[0] = (UBYTE)(rand()%25) + 127;
  816.  
  817.                         MidRdst[1] = (UBYTE)(rand()%24) + 0;
  818.                         MidGdst[1] = (UBYTE)(rand()%24) + 0;
  819.                         MidBdst[1] = (UBYTE)(rand()%24) + 0;
  820.  
  821.                         MidRdst[2] = (UBYTE)(rand()%24) + 0;
  822.                         MidGdst[2] = (UBYTE)(rand()%24) + 0;
  823.                         MidBdst[2] = (UBYTE)(rand()%24) + 0;
  824.                     break;
  825.  
  826.                     case 2:
  827.                         MidRdst[0] = (UBYTE)(rand()%24) + 0;
  828.                         MidGdst[0] = (UBYTE)(rand()%24) + 0;
  829.                         MidBdst[0] = (UBYTE)(rand()%24) + 0;
  830.  
  831.                         MidRdst[1] = (UBYTE)(rand()%24) + 0;
  832.                         MidGdst[1] = (UBYTE)(rand()%24) + 0;
  833.                         MidBdst[1] = (UBYTE)(rand()%24) + 0;
  834.  
  835.                         MidRdst[2] = (UBYTE)(rand()%24) + 0;
  836.                         MidGdst[2] = (UBYTE)(rand()%24) + 0;
  837.                         MidBdst[2] = (UBYTE)(rand()%24) + 0;
  838.                     break;
  839.  
  840.                     case 3:
  841.                         MidRdst[0] = (UBYTE)(rand()%25) + 0;
  842.                         MidGdst[0] = (UBYTE)(rand()%25) + 0;
  843.                         MidBdst[0] = (UBYTE)(rand()%25) + 0;
  844.  
  845.                         MidRdst[1] = (UBYTE)(rand()%24) + 0;
  846.                         MidGdst[1] = (UBYTE)(rand()%24) + 0;
  847.                         MidBdst[1] = (UBYTE)(rand()%24) + 0;
  848.  
  849.                         MidRdst[2] = (UBYTE)(rand()%24) + 0;
  850.                         MidGdst[2] = (UBYTE)(rand()%24) + 0;
  851.                         MidBdst[2] = (UBYTE)(rand()%24) + 0;
  852.                     break;
  853.  
  854.                     default:
  855.                         MidRdst[0] = (UBYTE)(rand()%25) + 127;
  856.                         MidGdst[0] = (UBYTE)(rand()%25) + 127;
  857.                         MidBdst[0] = (UBYTE)(rand()%25) + 127;
  858.  
  859.                         MidRdst[1] = (UBYTE)(rand()%25) + 64;
  860.                         MidGdst[1] = (UBYTE)(rand()%25) + 64;
  861.                         MidBdst[1] = (UBYTE)(rand()%25) + 64;
  862.  
  863.                         MidRdst[2] = (UBYTE)(rand()%25) + 32;
  864.                         MidGdst[2] = (UBYTE)(rand()%25) + 32;
  865.                         MidBdst[2] = (UBYTE)(rand()%25) + 32;
  866.                     break;
  867.                 }
  868.             }
  869.  
  870.             CalcLine(Zoom2, Width, Height, FieldToCalc);
  871.             LineToCalc++;
  872.             if(LineToCalc > Height-1) LineToCalc = Height-1;
  873.             FrameCountField++;
  874.             
  875.             if(FrameCountField > 500) {
  876.  
  877.             printf("FCF 500\n");
  878.                 FrameCountField=/*0*/1;
  879.  
  880.                 LineToCalc = /*0*/1;
  881.                 PrevField = FieldToCalc;
  882. //#ifndef __VBCC__
  883.                 do {
  884.             FieldToCalc=(UBYTE) rand() % NUMFIELDS;
  885.                 } while (FieldToCalc == PrevField);
  886.  
  887.                 for(j=0; j<Width*Height; j++)
  888.                 {
  889.                     Zoom[j]=Zoom2[j];
  890.                 }
  891.                 PrepareConstants(FieldToCalc);
  892. //#endif
  893.  
  894.             }
  895.  
  896.             for(i=Width*Cutoff; i<Width*(Height-Cutoff); i++) {
  897.                 PixelC[i]=PixelD[Zoom[i]];
  898.             }
  899.  
  900.             /* Make a backup of the data pointers */
  901.             PluginRawL    = SpecRawL;
  902.             PluginRawR    = SpecRawR;
  903.             PluginSamples = SampleRaw;
  904.  
  905.             InfoCount++;
  906.             if(InfoCount < 75) MakeTitle();
  907.             else InfoCount=75;
  908.  
  909.             TimeWave++;
  910.             FrameCountWave++;
  911.             CalcWave(WaveToCalc0, 0);
  912.             DrawWave(WaveX,  WaveY,  Width, Height, WaveToCalc0, 0);
  913.             CalcWave(WaveToCalc1, 1);
  914.             DrawWave(WaveX2, WaveY2, Width, Height, WaveToCalc1, 1);
  915.             if(FrameCountWave > 200) {
  916.  
  917.                 if(DestWaveBuffer == 1) WaveMorph += 0.005;
  918.                 else                    WaveMorph -= 0.005;
  919.             }
  920.             if (WaveMorph > 1.0) WaveMorph = 1.0;
  921.             if (WaveMorph < 0.0) WaveMorph = 0.0;
  922.  
  923.             if(FrameCountWave > 400) {
  924.             printf("FCW 400\n");
  925.             FrameCountWave = 0;
  926.             DestWaveBuffer = 1 - DestWaveBuffer;
  927. //#ifndef __VBCC__
  928.                 do {
  929. //#ifndef __VBCC__
  930.                     WaveToCalc = (UBYTE)rand() % NUMWAVES;
  931. //#else
  932. //                    WaveToCalc = NUMWAVES-1;
  933.  
  934. //#endif
  935.                 } while (WaveToCalc == WaveToCalc0 || WaveToCalc == WaveToCalc1);
  936.                 if(DestWaveBuffer == 1) {
  937.                     WaveToCalc1 = WaveToCalc;
  938.                     InitWave(WaveToCalc1, 1);
  939.                 }
  940.                 else {
  941.                     WaveToCalc0 = WaveToCalc;
  942.                     InitWave(WaveToCalc0, 0);
  943.                 }
  944. //#endif
  945.             }
  946.  
  947.             for(i=0; i<Width*2; i++) {
  948.                 float xf,yf;
  949.                 ULONG x,y;
  950.                 xf = (float)WaveX[i]*(1.0-WaveMorph) + (float)WaveX2[i]*(WaveMorph);
  951.                 yf = (float)WaveY[i]*(1.0-WaveMorph) + (float)WaveY2[i]*(WaveMorph);
  952.                 x  = (ULONG)xf + Width/2;
  953.                 y  = (ULONG)yf + Height/2;
  954.                 if(x < Width-1) {
  955.                     if(y < Height-1) {
  956.                         if(x > 0) {
  957.                             if(y > 0) {
  958.                                 ActPixel = PixelC + y * Width + x;
  959.                                 *ActPixel=255;
  960.                             }
  961.                         }
  962.                     }
  963.                 }
  964.             }
  965.  
  966.             SetAPen(rp, 0);
  967.             if(ShowWave) WritePixelArray(PixelC, 1, Cutoff+1, Width, rp, 0, Cutoff+1, Width-2, Height-2*Cutoff-2, RECTFMT_LUT8);
  968.             else         WritePixelArray(PixelD, 1, Cutoff+1, Width, rp, 0, Cutoff+1, Width-2, Height-2*Cutoff-2, RECTFMT_LUT8);
  969.             RectFill(rp, 0, 0, Width, Cutoff);
  970.             RectFill(rp, 0, Height-Cutoff-1, Width, Height-1);
  971.  
  972.             if(DisplayFPS)
  973.             {
  974.                 Move(rp, 0, 20);
  975.                 SetABPenDrMd(rp, 255, 0, JAM2);
  976.                 sprintf(FPStext, "%3ld fps       ", 5*eclock/itime);
  977.                 Text(rp, FPStext, 7);
  978.             }
  979.         }
  980.     }
  981. }
  982.  
  983.  
  984.  
  985. void Blur(UBYTE *PixelC, UBYTE *PixelD) {
  986.   UBYTE *ActPixel;
  987.   UBYTE *DstPixel;
  988.   UBYTE *AbovePixel, *BelowPixel;
  989.   UBYTE Left, Act, Right;
  990.   WORD w;
  991.   ULONG i;
  992.  
  993.     PixelC += Width*Cutoff;
  994.     PixelD += Width*Cutoff;
  995.  
  996.   ActPixel   = PixelC+Width+1;
  997.   AbovePixel = ActPixel-Width;
  998.   BelowPixel = ActPixel+Width;
  999.   DstPixel   = PixelD+Width+1;
  1000.  
  1001.   Left  = 0;
  1002.   Act   = 0;
  1003.   Right = 0;
  1004.  
  1005.     for(i=Width*(Cutoff+1); i<(Width*(Height-Cutoff-2)-2); i++) {
  1006.     Right = *(ActPixel+1);
  1007.  
  1008.     w = (Right + Act + Left + *AbovePixel + *BelowPixel) * 3 / 16;
  1009.         if(w<0) w=0;
  1010.     *DstPixel++ = w;
  1011.  
  1012.     ActPixel++;
  1013.     AbovePixel++;
  1014.     BelowPixel++;
  1015.  
  1016.     Left = Act;
  1017.     Act = Right;
  1018.   }
  1019. }
  1020.  
  1021. void ShowRequester(char *Text, char *Button) {
  1022.     struct EasyStruct Req;
  1023.     Req.es_StructSize   = sizeof(struct EasyStruct);
  1024.     Req.es_Flags        = 0;
  1025.   Req.es_Title        = "AmigaAMP Plugin";
  1026.   Req.es_TextFormat   = (UBYTE*)Text;
  1027.   Req.es_GadgetFormat = (UBYTE*)Button;
  1028.     EasyRequestArgs(NULL, &Req, NULL, NULL);
  1029. }
  1030.  
  1031. BOOL OpenTimer(void) {
  1032.     struct EClockVal ev = {0,0};
  1033.  
  1034.     if(TimerMP=(struct MsgPort*)CreatePort(0,0)) {
  1035.         if(TimerIO=(struct timerequest *)CreateIORequest(TimerMP, sizeof(struct timerequest))) {
  1036.             TimerError=OpenDevice("timer.device", UNIT_ECLOCK, (struct IORequest *)TimerIO, 0);
  1037.             if(TimerError==0) {
  1038.  
  1039.                 TimerBase = (struct Library*) &TimerIO->tr_node.io_Device->dd_Library;
  1040.                 EFreq=ReadEClock(&ev);
  1041.  
  1042.                 TimerMask = 1L << TimerMP->mp_SigBit;
  1043.  
  1044.                 return(TRUE);
  1045.             }
  1046.         }
  1047.     }
  1048.     return(FALSE);
  1049. }
  1050.  
  1051. void CloseTimer(void) {
  1052.     if(!TimerError)   CloseDevice((struct IORequest *)TimerIO);
  1053.     if(TimerIO)       DeleteIORequest(TimerIO);
  1054.     if(TimerMP)       DeletePort(TimerMP);
  1055. }
  1056.  
  1057. void StartTimer(void) {
  1058.     TimerIO->tr_node.io_Command = TR_ADDREQUEST;
  1059.     TimerIO->tr_node.io_Flags   = 0;
  1060.     TimerIO->tr_time.tv_secs    = 0;
  1061.     TimerIO->tr_time.tv_micro   = EFreq/LimitFPS;
  1062.     SendIO((struct IORequest *)TimerIO);
  1063. }
  1064.  
  1065. struct MsgPort *MyCreatePort(UBYTE *name, LONG pri) {
  1066.     int sigBit;
  1067.     struct MsgPort *mp;
  1068.  
  1069.     if((sigBit = AllocSignal(-1L)) == -1)    return(NULL);
  1070.  
  1071.     mp = (struct MsgPort*) AllocVec(sizeof(struct MsgPort), MEMF_PUBLIC|MEMF_CLEAR);
  1072.  
  1073.     if(!mp) {
  1074.         FreeSignal(sigBit);
  1075.         return(NULL);
  1076.     }
  1077.  
  1078.     mp->mp_Node.ln_Name = name;
  1079.     mp->mp_Node.ln_Pri  = pri;
  1080.     mp->mp_Node.ln_Type = NT_MSGPORT;
  1081.     mp->mp_Flags        = PA_SIGNAL;
  1082.     mp->mp_SigBit       = sigBit;
  1083.     mp->mp_SigTask      = FindTask(NULL);
  1084.     if(name) AddPort(mp);
  1085.     #if defined (__SASC) || defined (__VBCC__)
  1086.         else NewList(&(mp->mp_MsgList));
  1087.     #else
  1088.         else NewListPPC(&(mp->mp_MsgList));
  1089.     #endif
  1090.  
  1091.     return(mp);
  1092. }
  1093.  
  1094. void MyDeletePort(struct MsgPort *mp) {
  1095.     if(mp->mp_Node.ln_Name) RemPort(mp);
  1096.     mp->mp_SigTask         = (struct Task *) -1;
  1097.     mp->mp_MsgList.lh_Head = (struct Node *) -1;
  1098.     FreeSignal(mp->mp_SigBit);
  1099.     FreeVec(mp); mp=NULL;
  1100. }
  1101.  
  1102. void InitField(LONG *Zoom, ULONG Width, ULONG Height) {
  1103.     LONG i,xs,ys,xd,yd;
  1104.  
  1105.     float scale,greater;
  1106.     float xsf,ysf,xdf,ydf;
  1107.     float rsf,tsf,rdf,tdf;
  1108.     float wf,hf;
  1109.  
  1110.     wf=(float)Width;
  1111.     hf=(float)Height;
  1112.  
  1113.     greater=1.0;
  1114.     if(wf > greater) greater = wf;
  1115.     if(hf > greater) greater = hf;
  1116.  
  1117.     scale = 1.0 / (greater/2.0);
  1118.  
  1119.     for(yd=0; yd<(Height); yd++) {
  1120.         for(xd=0; xd<(Width); xd++) {
  1121.             xdf = (xd - wf/2.0) * scale;
  1122.             ydf = (yd - hf/2.0) * scale;
  1123.  
  1124.             xsf = xdf - xdf * 0.075;
  1125.             ysf = ydf - ydf * 0.075;
  1126.  
  1127.             xs = xsf/scale + wf/2.0;
  1128.             ys = ysf/scale + hf/2.0;
  1129.  
  1130.             if(xs < Width/2)  xs++;
  1131.             if(ys < Height/2) ys++;
  1132.  
  1133.             if(xs < 0)      xs = 0;
  1134.             if(xs > Width)  xs = Width;
  1135.             if(ys < 0)      ys = 0;
  1136.             if(ys > Height) ys = Height;
  1137.  
  1138.             Zoom[Width * yd + xd] = Width * ys + xs;
  1139.         }
  1140.     }
  1141. }
  1142.  
  1143.  
  1144. void MakeCMap(void) {
  1145.     int j,i,c;
  1146.     float r,g,b;
  1147.     float rs,gs,bs;
  1148.  
  1149.     r=255; g=255; b=255;
  1150.  
  1151.     c=255;
  1152.  
  1153.     Colour[0]=256L<<16+0;
  1154.  
  1155.     for(j=0; j<4; j++) {
  1156.         rs = (r - (float)MidR[j]) / 64.0;
  1157.         gs = (g - (float)MidG[j]) / 64.0;
  1158.         bs = (b - (float)MidB[j]) / 64.0;
  1159.         for(i=0; i<64; i++) {
  1160.             Colour[1+3*c+0] = (ULONG)r << 24;
  1161.             Colour[1+3*c+1] = (ULONG)g << 24;
  1162.             Colour[1+3*c+2] = (ULONG)b << 24;
  1163.             r -= rs;
  1164.             g -= gs;
  1165.             b -= bs;
  1166.             c--;
  1167.         }
  1168.     }
  1169.  
  1170. }
  1171.  
  1172. void MakeTitle(void) {
  1173.     long x,y,i,p,s,v,xs,ys;
  1174.     UWORD Blt1[27] = {
  1175.         0x7008,0x0000,0x0000,0x8808,0x0000,0x0000,0x822B,0x1963,
  1176.         0x8E38,0x722C,0xA590,0x5144,0x0A28,0x9913,0xD07C,0x8A28,
  1177.         0x8514,0x5040,0x8A68,0xA594,0xD144,0x71AF,0x1963,0x4E38,
  1178.         0x0000,0x0100,0x0000
  1179.     }; // W=46, H=9
  1180.     UWORD Blt2[54] = {
  1181.         0x8001,0xF400,0x0000,0x0101,0x0000,0x0080,0x8000,0x4400,
  1182.         0x0000,0x0111,0x0000,0x0080,0xB220,0x458E,0x7638,0xC111,
  1183.         0x3967,0x9C80,0xCA20,0x4651,0x4905,0x2092,0x4590,0xA280,
  1184.         0x8940,0x4451,0x493C,0xC0AA,0x7D11,0x3E80,0x8940,0x4451,
  1185.         0x4944,0x20AA,0x4112,0x2080,0x8880,0x4451,0x494D,0x2044,
  1186.         0x4514,0x2280,0xF080,0x444E,0x4934,0xC044,0x3917,0x9C80,
  1187.         0x0100,0x0000,0x0000,0x0000,0x0000,0x0000
  1188.     }; // W=89, H=9
  1189.  
  1190.     xs = (Width-46)/2;
  1191.     ys = Height/2-30-9;
  1192.     s=0;
  1193.     for(y=0; y<9; y++) {
  1194.         x=0;
  1195.         for(i=0; i<3; i++) {
  1196.             for(p=0; p<16; p++) {
  1197.                 x++;
  1198.                 v = Blt1[s] & (1<<(15-p));
  1199.                 if(v) PixelC[(ys+y)*Width+xs+x] = 255;
  1200.             }
  1201.             s++;
  1202.         }
  1203.     }
  1204.     xs = (Width-89)/2;
  1205.     ys = Height/2+30;
  1206.     s=0;
  1207.     for(y=0; y<9; y++) {
  1208.         x=0;
  1209.         for(i=0; i<6; i++) {
  1210.             for(p=0; p<16; p++) {
  1211.                 x++;
  1212.                 v = Blt2[s] & (1<<(15-p));
  1213.                 if(v) PixelC[(ys+y)*Width+xs+x] = 255;
  1214.             }
  1215.             s++;
  1216.         }
  1217.     }
  1218. }
  1219.  
  1220.  
  1221. void ReColor(void) {
  1222.  
  1223.     int i;
  1224. #ifndef __VBCC__ //don't change with VBCC because of broken rand()
  1225.     for(i=0; i<3; i++) {
  1226.         if(MidR[i] > MidRdst[i]) MidR[i] --;
  1227.         if(MidG[i] > MidGdst[i]) MidG[i] --;
  1228.         if(MidB[i] > MidBdst[i]) MidB[i] --;
  1229.         if(MidR[i] < MidRdst[i]) MidR[i] ++;
  1230.         if(MidG[i] < MidGdst[i]) MidG[i] ++;
  1231.         if(MidB[i] < MidBdst[i]) MidB[i] ++;
  1232.     }
  1233. #endif
  1234.     MakeCMap();
  1235.     LoadRGB32(&PluginScreen->ViewPort, Colour);
  1236. }
  1237.  
  1238. float rnd(float max) {
  1239.     ULONG r;
  1240.     ULONG m;
  1241.  
  1242.     m = (ULONG)(max * 10000.0);
  1243.  
  1244.     r=(rand()) % m;
  1245.  
  1246.     return (float)r/10000.0;
  1247. }
  1248.  
  1249. float sgn(float val) {
  1250.     if(val > 0.0) return  1.0;
  1251.     if(val < 0.0) return -1.0;
  1252.     return 0.0;
  1253. }
  1254.  
  1255. float trnc(float value) {
  1256.     return ceil(value);
  1257. }
  1258.  
  1259. #ifdef __SASC
  1260. void SetPriority(void) {
  1261.     struct TagItem MyTags[2];
  1262.     if(PPCLibBase=OpenLibrary("ppc.library",0)) {
  1263.         MyTags[0].ti_Tag  = PPCTASKTAG_PRIORITY;
  1264.         MyTags[0].ti_Data = 15;
  1265.         MyTags[1].ti_Tag     = TAG_END;
  1266.         CloseLibrary(PPCLibBase);
  1267.     }
  1268. }
  1269. #endif
  1270.  
  1271.  
  1272.  
  1273.  
  1274.  
  1275.  
  1276.